<?php
/**
 * Created by PhpStorm.
 * User: 秋枫雁飞
 * Date: 2019/5/10
 * Time: 12:15
 */

namespace Aiweline\Core\Helper;

use Magento\Email\Model\Template\SenderResolver;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;
use Mageplaza\Smtp\Helper\Data as SmtpData;
use Mageplaza\Smtp\Mail\Rse\Mail;
use Aiweline\Core\Debug\Debug;
use PHPUnit\Runner\Exception;

class EmailSender extends AbstractHelper
{
    const smtp_CONFIG_PATH = 'smtp/configuration_option';
    const mjd_CORE_EMAIL = 'Aiweline_Core_admin/email';

    protected $db = null;
    /**
     * Sender email config path - from default CONTACT extension
     */
    /**
     * Store manager
     *
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var \Magento\Framework\Translate\Inline\StateInterface
     */
    private $inlineTranslation;

    /**
     * @var \Magento\Framework\Mail\Template\TransportBuilder
     */
    private $transportBuilder;
    private $debug;
    /**
     * @var SmtpData
     */
    protected $smtpDataHelper;

    /**
     * @var Mail
     */
    protected $mailResource;
    /**
     * @var SenderResolver
     */
    protected $senderResolver;
    protected $messageManager;
    public $status = false;
    /*
     * default config
     * */
    protected $_smtpConfig = false;
    protected $_coreConfig = false;
    protected $_customConfig = false;
    protected $_variable = false;
    protected $_emailSender = false;
    protected $_emailTemplateId = false;
    protected $_area = false;

    /**
     * Demo constructor.
     * @param \Magento\Framework\App\Helper\Context $context
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
     * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
     * @param \Magento\Framework\Message\ManagerInterface $managerInterface
     * @param SmtpData $smtpDataHelper
     * @param Mail $mailResource
     * @param SenderResolver $senderResolver
     * @param Debug $debug
     * @param \Aiweline\Core\Helper\Mdb $mdb
     * @throws \Exception
     */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
        , \Magento\Framework\Message\ManagerInterface $managerInterface
        , SmtpData $smtpDataHelper
        , Mail $mailResource
        , SenderResolver $senderResolver
        , Debug $debug
        , Mdb $mdb
    )
    {
        parent::__construct($context);
        $this->db = $mdb;
        $this->smtpDataHelper = $smtpDataHelper;
        $this->mailResource = $mailResource;
        $this->storeManager = $storeManager;
        $this->inlineTranslation = $inlineTranslation;
        $this->transportBuilder = $transportBuilder;
        $this->messageManager = $managerInterface;
        $this->senderResolver = $senderResolver;
        $this->debug = $debug;
        $this->_smtpConfig = $this->getSmtpConfig();
        $this->_coreConfig = $this->getConfigValue(self::mjd_CORE_EMAIL);
        $this->_emailTemplateId = $this->_coreConfig['email_template'];
        $this->_area = $this->setArea();
    }

    /**
     * Return store configuration value of your template field that which id you set for template
     * 返回配置
     * @param string $path
     * @return mixed
     */
    public function getConfigValue($path)
    {
        return $this->scopeConfig->getValue(
            $path,
            ScopeInterface::SCOPE_STORE,
            $this->getStore()->getId()
        );
    }

    /**
     * Return store
     * 返回店铺
     * @return \Magento\Store\Api\Data\StoreInterface
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    private function getStore()
    {
        return $this->storeManager->getStore();
    }

    /**
     * 获取Smtp配置
     * @return array
     *
     */
    protected function getSmtpConfig()
    {
        $smtpConfig = $this->getConfigValue(self::smtp_CONFIG_PATH);
        $config = [
            'type' => 'smtp',
            'host' => $smtpConfig['host'],
            'auth' => $smtpConfig['authentication'],
            'username' => $smtpConfig['username'],
            'ignore_log' => true,
            'force_sent' => true
        ];
        if ($smtpConfig['protocol']) {
            $config['ssl'] = $smtpConfig['protocol'];
        }
        if ($smtpConfig['port']) {
            $config['port'] = $smtpConfig['port'];
        }
        $config['password'] = $this->smtpDataHelper->getPassword();
        if ($smtpConfig['return_path_email']) {
            $config['return_path'] = $smtpConfig['return_path_email'];
        }
        return $config;
    }

    /**
     * 获取配置：默认是核心配置
     * @return bool|mixed
     */
    public function getCustomConfig()
    {
        return $this->_customConfig ? $this->_customConfig : $this->_coreConfig;
    }

    /**
     * 生成模板
     * @param $variable
     * @param $receiverInfo
     * @param $templateId
     * @param $form
     * @return $this
     */
    private function generateTemplate($variable, $receiverInfo, $templateId, $form)
    {
        $this->transportBuilder->setTemplateIdentifier($templateId)
            ->setTemplateOptions(
                [
                    'area' => \Magento\Framework\App\Area::AREA_ADMINHTML,
                    'store' => $this->storeManager->getStore()->getId(),
                ]
            )
            ->setTemplateVars($variable)
            ->setFrom($form)
            ->addTo($receiverInfo['email'], $receiverInfo['name']);
        return $this;
    }

    /**
     * 设置模板：默认使用核心模块
     * Return email for sender header
     * @param string $email_config_path
     * @return mixed
     * @throws \Exception
     */
    private function setEmailSender($email_config_path = '')
    {
        if (empty($email_config_path)) {
            $this->_emailSender = ['email' => $this->_smtpConfig['username'], 'name' => $this->_coreConfig['admin_name']];
            return $this->_emailSender;
        } else if (is_string($email_config_path)) {
            $this->_customConfig = $this->_customConfig ? $this->_customConfig : $this->getConfigValue($email_config_path);
            $this->_emailSender = ['email' => $this->_smtpConfig['username'], 'name' => $this->_customConfig['admin_name']];
            return $this;
        } else {
            throw new \Exception("Error mail configuration parameters.Must be the configuration path of the string type");
        }
    }

    /**
     * 获取发送者:默认是核心发送者
     * @return bool
     */
    public function getEmailSender()
    {
        return $this->_emailSender ? $this->_emailSender : $this->setEmailSender();
    }

    /**
     * 设置配置：默认使用核心模块
     * @param string $email_config_path
     * @return $this
     * @throws \Exception
     */
    public function setData($email_config_path = '')
    {
        if (empty($email_config_path)) {
            $this->setVariable();
            $this->setEmailSender();
            return $this;
        } else if (is_string($email_config_path)) {
            $this->_customConfig = $this->_customConfig ? $this->_customConfig : $this->getConfigValue($email_config_path);
            $this->setVariable($email_config_path);
            $this->setEmailSender($email_config_path);
            return $this;
        } else {
            throw new \Exception("Error mail configuration parameters.Must be the configuration path of the string type");
        }
    }

    /**
     * 配置邮件前后台区域
     * @param string $area
     * @return $this
     * @throws \Exception
     */
    public function setArea($area = '')
    {
        if (empty($area)) {
            $this->_area = \Magento\Framework\App\Area::AREA_ADMINHTML;
            return $this;
        } else if (is_string($area)) {
            if ($area == \Magento\Framework\App\Area::AREA_FRONTEND) {
                $this->_area = \Magento\Framework\App\Area::AREA_FRONTEND;
            } else {
                $this->_area = \Magento\Framework\App\Area::AREA_ADMINHTML;
            }
            return $this;
        } else {
            throw new \Exception("Error mail area.Must be the string type");
        }
    }

    /**
     * 设置模板id:默认使用核心模板
     * @param string $email_config_path
     * @return $this
     * @throws \Exception
     */
    public function setTemplateId($email_config_path = '')
    {
        if (empty($email_config_path)) {
            $this->_emailTemplateId = $this->_coreConfig['email_template'];
            return $this;
        } else if (is_string($email_config_path)) {
            $this->_customConfig = $this->_customConfig ? $this->_customConfig : $this->getConfigValue($email_config_path);
            $this->_emailTemplateId = $this->_customConfig['email_template'];
            return $this;
        } else {
            throw new \Exception("Error mail configuration parameters.Must be the configuration path of the string type");
        }

    }

    /**
     * 设置模板变量:如果不设置将使用核心模板配置
     * @param string $email_config_path
     * @return mixed
     * @throws \Exception
     */
    public function setVariable($email_config_path = '')
    {
        if (empty($email_config_path)) {
            $this->_variable = $this->_coreConfig;
            return $this->_variable;
        } else if (is_string($email_config_path)) {
            $this->_customConfig = $this->_customConfig ? $this->_customConfig : $this->getConfigValue($email_config_path);
            $this->_variable = $this->_customConfig;
            return $this;
        } else {
            throw new \Exception("Error mail configuration parameters.Must be the configuration path of the string type");
        }
    }

    public function asyncEmail($to_name, $to_email, $message, $module = '')
    {
        $insert_data = array(
            'module' => empty($module) ? $this->_getModuleName() : $module,
            'to_name' => $to_name,
            'to_email' => $to_email,
            'send_message' => $message,
            'create_time' => date('Y-m-d H:m:s'),
            'send_time' => 0,
            'status' => 0
        );
        return $this->db
            ->table(\Aiweline\Core\Setup\InstallSchema::table_MJD_EMAIL_WAIT_SEND_ENTITY)
            ->insert($insert_data)
            ->fetch();
    }

    /**
     * 发送邮件
     * @param $to_name
     * @param $to_email
     * @param string $message
     * @return $this
     * @internal param $name
     * @internal param $email
     */
    public function sendEmail($to_name, $to_email, $message = '')
    {

        /* 接收者信息Receiver Detail */
        $receiverInfo = [
            'name' => $to_name,
            'email' => $to_email
        ];

        /* 模板变量配置  */
        $variable = $this->_variable ? $this->_variable : $this->setVariable();
        /*自定义消息变量*/
        $variable['message_content'] = $message;
        /*模板ID*/
        $templateId = $this->_emailTemplateId ? $this->_emailTemplateId : $this->setTemplateId();
        /*发送者配置*/
        $emailSender = $this->_emailSender ? $this->_emailSender : $this->setEmailSender();
        //$this->inlineTranslation->suspend();
        /*配置发送选项*/
        $this->mailResource->setSmtpOptions($this->getStore()->getId(), $this->_smtpConfig);
        /*配置邮件来源*/
        $from = $this->senderResolver->resolve(
            $emailSender,
            $this->smtpDataHelper->getScopeId()
        );
        /*生成邮件模板*/
        $this->generateTemplate($variable, $receiverInfo, $templateId, $from);
        /*尝试发送邮件*/
        try {
            $this->transportBuilder->getTransport()->sendMessage();
            $this->debug->de_pass_bug('发送成功:The receiver name is ' . $receiverInfo['name'] . ',email is ' . $receiverInfo['email']);
            $this->status = true;
        } catch (\Exception $e) {
            $this->debug->de_pass_print('发送失败:' . \GuzzleHttp\json_encode($e));
            $this->messageManager->addErrorMessage('Send email error.The receiver name is ' . $receiverInfo['name'] . ',email is ' . $receiverInfo['email']);
            $this->debug->de_pass_bug($e, 'Aiweline_Core:自定义邮件发送错误！');
            $this->status = false;
        }
        /*邮件管道重新使用*/
        $this->inlineTranslation->resume();
        return $this;
    }
}